#include "aac_one_frame_get.h"

#define adts_heaer_size  7

static aac_adts_info s_adts_info;

#define AAC_BUFFER_SIZE (100 * 1024) 

char aac_buffer[AAC_BUFFER_SIZE];

static int verify_aac_header(unsigned char *data, int length,
                            int first_header, int *samplerate,
                            int *channel_num, int *frame_length)
{
	if(length < adts_heaer_size){
		printf("data length is  %d less than adts_heaer_size %d\n", length, adts_heaer_size); 
		return 0;
	}
	else
    {
		if(!first_header)
        {
			int syncword = 0;
			unsigned char tmp = data[1] &0xf0;
			if((data[0] != 0xff) && (tmp != 0xf0)){
				printf("syncword err\n"); 
				return 0;
			}
			syncword = 1;
			*channel_num = ((data[3]) >> 6);
			int feq_index =  ((data[2] & 0x3f) >> 2);
		//	printf(" feq_index = %d\n",feq_index); 
			if(feq_index == 0){
				* samplerate = 96000;
			}
			else if(feq_index == 1){
				* samplerate = 88200;
			}
			else if(feq_index == 2){
				* samplerate = 64000;
			}
			else if(feq_index == 3){
				* samplerate = 48000;
			}
			else if(feq_index == 4){
				* samplerate = 44100;
			}
			else if(feq_index == 5){
				* samplerate = 32000;
			}
			else if(feq_index == 6){
				* samplerate = 24000;
			}
			else if(feq_index == 7){
				* samplerate = 22050;
			}
			else if(feq_index == 8){
				* samplerate = 16000;
			}
			else if(feq_index == 9){
				* samplerate = 12000;
			}
			else if(feq_index == 10){
				* samplerate = 11025;
			}
			else if(feq_index == 11){
				* samplerate = 8000;
			}
			else if(feq_index == 12){
				* samplerate = 7350;
			}
			else{
				printf("samplerate is error for  feq_index = %d\n",feq_index); 
				return 0;
			}
			* frame_length = (((data[3] & 0x03)<< 11) +  (data[4] << 3) + (data[5] >> 5));
		//	printf("samplerate %d,  frame_length =%d\n",* samplerate,  * frame_length);
			memcpy(s_adts_info.verify_byte, &data[0], 4);
			s_adts_info.verify_byte[3] = ((s_adts_info.verify_byte[3] >> 2 ) << 2);
			s_adts_info.frame_length = (* frame_length);
			s_adts_info.channel_num = (*channel_num);
			s_adts_info.samplerate = (*samplerate);
		}
		else
        {
			unsigned char tmp = data[3] & 0xfb;
			if(data[0] != s_adts_info.verify_byte[0] || data[1] != s_adts_info.verify_byte[1] 
			|| data[2] != s_adts_info.verify_byte[2] || s_adts_info.verify_byte[3] != tmp){
				//printf("verify first header error\n");
				return 0;
			}
			* frame_length = (((data[3] & 0x03)<< 11) +  (data[4] << 3) + (data[5] >> 5));
			//ERR("samplerate %d,  frame_length =%d\n", s_adts_info.samplerate,  * frame_length);
			//printf(" frame_length =%d\n", * frame_length);
			s_adts_info.frame_length = (* frame_length);
		}
		return 1;
	}
}

int aac_one_frame_get_init(aac_get_info *info){
	memset(info, 0, sizeof(aac_get_info));
	info->adts_info.samplerate = 0;
	info->buffer = aac_buffer;
	info->buffer_size = AAC_BUFFER_SIZE;
	info->used_len = 0;
	info->cur_frame_index = 0;
	info->cur_frame_addr = 0;
	info->next_frame_addr = 0;
	info->find_first_frame = 0;
	info->num = 0;
	info->find_flag = 0;
	info->first_find_flag = 0;
	info->ts_used_flag = 1;
	return 1;
}

int aac_one_frame_get_process(aac_get_info *info, char *src_buffer,
                              int src_len ,char * dst_buffer, int *buffer_length)
{
	if( info->used_len + src_len > info->buffer_size) // overflow judge
	{
		info->used_len = 0;
		memset(info->buffer,0x00,info->buffer_size);
		info->next_frame_addr = 0;
		info->cur_frame_addr = 0; 
		info->find_flag = 0;
		info->num = 0;
		memcpy(info->buffer,src_buffer,src_len);
		info->used_len += src_len;
        printf("aac_one_frame_get_process buffer is full!\n");
	}
	else
	{
		memcpy(info->buffer + info->used_len,src_buffer,src_len);
		info->used_len += src_len;
	}

	if(info->next_frame_addr >= info->used_len-adts_heaer_size){
		info->find_flag = 2;
		return info->find_flag;
	}
	while (info->next_frame_addr < info->used_len-adts_heaer_size)
	{
		int samplerate = 0;
		int channel_num = 0;
		int frame_length = 0;
			
		if(verify_aac_header((unsigned char *)(&(info->buffer[info->next_frame_addr])), adts_heaer_size, 
			info->first_find_flag, &samplerate, &channel_num, &frame_length))
		{     
			if(info->first_find_flag == 0)
			{
				info->first_find_flag = 1;
				info->adts_info.samplerate = samplerate;
				info->adts_info.channel_num = channel_num;
				printf("info->adts_info.samplerate  =%d\n", info->adts_info.samplerate );
				printf("info->adts_info.channel_num  =%d\n", info->adts_info.channel_num );
			//	printf("info->adts_info.frame_length  =%d\n", info->adts_info.frame_length );
			}
			if(info->find_first_frame == 0)
			{
				info->cur_frame_addr = info->next_frame_addr;	
				info->adts_info.frame_length = frame_length;
				info->find_first_frame = 1;	
				
			}
			info->num ++; 
			if(info->num == 1)
            {
				if(info->next_frame_addr + frame_length - 1 <  info->used_len)
                {
					info->next_frame_addr += frame_length - 1;
				}
			}
			if (info->num == 2) 
			{
				info->find_flag = 1;
				break;
			}
		}
		info->next_frame_addr++;
	}
	if (info->find_flag == 1)
	{
		if( info->next_frame_addr - info->cur_frame_addr == info->adts_info.frame_length)
        {
			*buffer_length = info->next_frame_addr - info->cur_frame_addr;
		}
		else{
			info->find_flag = 0;
			*buffer_length  = 0;
		}
		memcpy(dst_buffer, info->buffer +info->cur_frame_addr, *buffer_length);
		memcpy(info->buffer, info->buffer + info->next_frame_addr, info->used_len - info->next_frame_addr );
		info->used_len = info->used_len - info->next_frame_addr;
		info->next_frame_addr = 0;
		info->find_first_frame = 0;
		info->find_flag = 0;
		info->num = 0;
	}
	else
	{
		*buffer_length = 0;
	}
	return info->find_flag;
}

int aac_one_frame_get_exit(aac_get_info *info)
{
	memset(info, 0, sizeof(aac_get_info));
	info->adts_info.samplerate = 0;
	info->ts_used_flag = 0;
	info->first_find_flag = 0;
	return 0;
}

